﻿
namespace HSS.Xaml.UI.Controls
{
	#region Using Directives
	using System;
	using System.Collections;
	using System.Windows.Controls;
	using HSS.ComponentModel;
	using HSS.Resources;
	using System.Windows;


	#endregion

	#region CollectionValueEditor
	/// <summary>
	/// CollectionValueEditor
	/// </summary>
	public class CollectionValueEditor : PropertyGridEditor
	{
		#region Fields
		IEditorDialog dialog;
		Button button;
		bool isReadOnly;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="descriptor">The <see cref="HSSPropertyDescriptor"/> being edited.</param>
		public CollectionValueEditor(HSSPropertyDescriptor descriptor)
			: base(descriptor)
		{
			Guard.ArgumentNotNull(descriptor, "descriptor");
			this.isReadOnly = descriptor.IsReadOnly;
			this.button = new Button();
			this.button.Margin = new System.Windows.Thickness(0);
			this.button.Padding = new System.Windows.Thickness(4, 1, 4, 1);
			this.button.Content = "...";
			this.SkipSetValue = true;
		}
		#endregion

		#region Overrides
		/// <summary>
		/// Inline edit is readonly
		/// </summary>
		/// <returns></returns>
		protected override System.Windows.FrameworkElement CreateInlineEditControl()
		{
			return new LabelTextBox
			{
				Margin = new Thickness(0),
				BorderThickness = new Thickness(0),
				HorizontalAlignment = HorizontalAlignment.Stretch,
				IsReadOnly = true
			};
		}
		/// <summary>
		/// Get the button to show for a Dialog Editor.
		/// </summary>
		/// <returns>A <see cref="System.Windows.Controls.Button"/> instance.</returns>
		public override System.Windows.Controls.Button GetDialogEditButton()
		{
			return button;
		}
		/// <summary>
		/// Gets if this editor supports showing a Dialog Editor.
		/// </summary>
		public override bool SupportsEditDialog
		{
			get { return true; }
		}
		/// <summary>
		/// Shows the Dialog Editor.
		/// </summary>
		protected override void ShowEditDialogInternal()
		{
			if (null != this.dialog)
				this.dialog.Close();

			var pt = this.PropertyEntry.Descriptor.Property.PropertyType;

			Type elementType = null;
			if (pt.HasElementType)
				elementType = pt.GetElementType();
			else
				elementType = pt.GetProperty("Item").PropertyType;

			if (elementType == typeof(string))
				dialog = new StringCollectionEditorDialog(this.PropertyEntry);
			else
				dialog = new CollectionEditorDialog(this.PropertyEntry, elementType);

			dialog.Closed += CollectionEditorDialog_Closed;
			dialog.Show();
		}
		/// <summary>
		/// Gets the controls editing value.
		/// </summary>
		/// <returns>The value.</returns>
		protected override object GetControlValue()
		{
			// Collection editor doesn't return a value.
			return null;
		}
		/// <summary>
		/// Updates the displayed control with the new value.
		/// </summary>
		/// <param name="newValue">The new value.</param>
		protected override void UpdateDisplayControl(object newValue)
		{
			var pt = this.PropertyEntry.Descriptor.Property.PropertyType;

			Type elementType = null;
			if (pt.HasElementType)
				elementType = pt.GetElementType();
			else
				elementType = pt.GetProperty("Item").PropertyType;

			var count = null == newValue ? 0 : ((IList)newValue).Count;
			base.UpdateDisplayControl(ResourceProvider.GetString(StringKeys.CollectionValueEditor_TitleFormat, elementType.Name, count));
		}
		/// <summary>
		/// Not used.
		/// </summary>
		/// <param name="newValue"></param>
		protected override void UpdateInlineEditControl(object newValue)
		{
			var pt = this.PropertyEntry.Descriptor.Property.PropertyType;

			Type elementType = null;
			if (pt.HasElementType)
				elementType = pt.GetElementType();
			else
				elementType = pt.GetProperty("Item").PropertyType;

			var count = null == newValue ? 0 : ((IList)newValue).Count;
			((TextBox)this.InlineEditControl).Text = ResourceProvider.GetString(StringKeys.CollectionValueEditor_TitleFormat, elementType.Name, count);
		}

		#endregion

		#region Event Handlers
		void CollectionEditorDialog_Closed(object sender, EventArgs e)
		{
			this.dialog.Closed -= CollectionEditorDialog_Closed;
			var d = dialog as ICancellableEditorDialog;
			this.dialog = null;
			if (null != d)
			{
				if (this.isReadOnly)
				{
					this.CancelEdit();
				}
				else
				{
					if (d.DialogResult == true)
					{
						d.EndEdit();
						this.EndEdit();
					}
					else
						this.CancelEdit();
				}
			}
			else
			{
				var d2 = sender as IEditorDialog;
				if (this.isReadOnly)
				{
					this.CancelEdit();
				}
				else
				{
					d2.EndEdit();
					this.EndEdit();
				}
			}
		}
		#endregion
	}
	#endregion
}